package hos.location;

import android.content.Context;
import android.location.Location;
import android.util.Base64;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import hos.map.coordinate.CoordinateType;
import hos.map.coordinate.LatLng;

/**
 * <p>Title: LocationDataAndroid </p>
 * <p>Description: 定位数据工具类 </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023-12-10 22:21
 */
public class LocationDataUtils {

    private LocationDataUtils() {
    }

    public static LocationData convertLocation(android.location.Location androidLocation) {
        if (androidLocation == null) {
            return null;
        }
        return new LocationData.Builder(CoordinateType.wgs84)
                .provider(androidLocation.getProvider())
                .latitude(androidLocation.getLatitude())
                .longitude(androidLocation.getLongitude())
                .accuracy(androidLocation.getAccuracy())
                .direction(androidLocation.getBearing())
                .speed(androidLocation.getSpeed())
                .altitude(androidLocation.getAltitude())
                .satellitesNum(0)
                .build();
    }

    public static Location convertLocation(LocationData locationData) {
        if (locationData == null) {
            return null;
        }
        Location location = new Location(locationData.provider);
        location.setLatitude(locationData.latLng.getLatitude());
        location.setLongitude(locationData.latLng.getLongitude());
        location.setAccuracy(locationData.accuracy);
        location.setBearing(locationData.direction);
        location.setSpeed(locationData.speed);
        location.setAltitude(locationData.altitude);
        location.setTime(locationData.time);
        return location;
    }

    public static LocationData fromJson(String jsonData) {
        if (jsonData == null || jsonData.length() == 0) {
            return null;
        }

        try {
            JSONObject jsonObject = new JSONObject(jsonData);

            // 必须字段检查
            String typeStr = jsonObject.getString("type");
            CoordinateType type = CoordinateType.form(typeStr);

            String json = jsonObject.optString("json");
            String provider = jsonObject.optString("provider");

            String address = jsonObject.optString("address", "");
            List<String> addressLines = new ArrayList<>();
            if (address.length() != 0) {
                if (address.contains(",")) {
                    addressLines.addAll(Arrays.asList(address.split(",")));
                } else {
                    addressLines.add(address);
                }
            }

            double latitude = jsonObject.getDouble("latitude");
            double longitude = jsonObject.getDouble("longitude");
            double accuracy = jsonObject.optDouble("accuracy");
            double speed = jsonObject.optDouble("speed");
            double direction = jsonObject.optDouble("direction");
            double altitude = jsonObject.optDouble("altitude");
            int satellitesNum = jsonObject.optInt("satellitesNum");
            double header = jsonObject.optDouble("header");
            long time = jsonObject.optLong("time");

            LatLng latLng = new LatLng(latitude, longitude, type);
            latLng.setJson(json);

            return new LocationData.Builder(latLng)
                    .provider(provider)
                    .latitude(latitude)
                    .longitude(longitude)
                    .accuracy((float) accuracy)
                    .altitude(altitude)
                    .speed((float) speed)
                    .direction((float) direction)
                    .header(header)
                    .satellitesNum(satellitesNum)
                    .address(addressLines)
                    .time(time)
                    .build();

        } catch (JSONException e) {
            // 使用日志框架替代 printStackTrace()
            Log.e("LocationData", "JSON解析失败: " + jsonData, e);
        } catch (Exception e) {
            Log.e("LocationData", "未知错误发生在JSON解析过程中", e);
        }

        return null;
    }


    public static boolean writeLocation(String key, String path, String location) {
        File cacheFile = LocationFileUtils.getCacheFile(path, key);
        if (location == null || location.length() == 0) {
            return false;
        }
        byte[] encode = Base64.encode(location.getBytes(), Base64.NO_WRAP);
        return LocationFileUtils.writeFileFromBytesByStream(cacheFile, encode);
    }

    public static LocationData readLocation(Context context, String key, String path) {
        File cacheFile = LocationFileUtils.getCacheFile(path, key);
        byte[] bytes;
        if (context == null) {
            bytes = LocationFileUtils.readFile2BytesByStream(cacheFile);
        } else {
            bytes = LocationFileUtils.readFile2BytesByStream(context, cacheFile);
        }
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        byte[] decode = Base64.decode(bytes, Base64.NO_WRAP);
        if (decode == null || decode.length == 0) {
            return null;
        }
        return fromJson(new String(decode));
    }

}
